package demo.dubbo.provider.filter;

import java.util.Collection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;

/**
 * 日志
 * 
 * @author hanjy
 *
 */
@Activate(group = Constants.PROVIDER)
public class DubboLogFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger("DubboLogFilter");

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) {
        long t0 = System.currentTimeMillis();
        Result res = invoker.invoke(invocation);
        long cost = System.currentTimeMillis() - t0;
        log(invocation, cost);
        return res;
    }

    public static void log(Invocation invocation, long cost) {
        try {
            Object[] arguments = invocation.getArguments();
            int argumentSize = arguments.length;
            Class<?>[] parameterTypes = invocation.getParameterTypes();
            Object[] logStr = new Object[arguments.length];
            for (int i = 0; i < argumentSize; i++) {
                if (String.class.isAssignableFrom(parameterTypes[i])) {
                    int length = arguments[i].toString().length();
                    logStr[i] = length > 100 ? "string.length=" + length : arguments[i];
                } else if (Collection.class.isAssignableFrom(parameterTypes[i])) {
                    int size = ((Collection) arguments[i]).size();
                    logStr[i] = "collection.size=" + size;
                } else {
                    logStr[i] = arguments[i];
                }
            }
            logger.info("{},cost:{},args:{}", invocation.getMethodName(), cost, logStr);
        } catch (Exception e) {
            logger.error("", e);
        }
    }
}